package org.one.afternoon.common;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.one.afternoon.domain.Statistic;
import org.one.afternoon.service.HospitalService;
import org.one.afternoon.service.StatisticService;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

public class DayOfTheWeek {

    /***
     * 传入一个日期并判断这一天为一周中的星期几
     * @param date 日期
     * @return 星期几
     */
    public static int dayOfTheWeek(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        boolean isFirstSunday = (calendar.getFirstDayOfWeek() == Calendar.SUNDAY);

        int weekday = calendar.get(Calendar.DAY_OF_WEEK);
        if (isFirstSunday) {
            weekday -= 1;
            if (weekday == 0) {
                weekday = 7;
            }
        }

        return weekday;
    }

    /***
     * 通过type类型组装并返回两周以内的数据集合
     * @param type 人群类型
     * @param statisticService statistic的服务类 用于调用其内部方法
     * @param hospitalService hospital的服务类 用于调用其内部方法
     * @return 返回指定类型人群两周内的记录
     */
    public static List<Long> twoWeeksList(String type, StatisticService statisticService, HospitalService hospitalService) {
        //用于查询记录的详细信息的条件构造器
        LambdaQueryWrapper<Statistic> lambdaQueryWrapper = new LambdaQueryWrapper<>();

        //查询最后一条记录的条件构造器
        LambdaQueryWrapper<Statistic> lastDayWrapper = new LambdaQueryWrapper<>();

        //查询第一条记录的条件构造器
        LambdaQueryWrapper<Statistic> firstDayWrapper = new LambdaQueryWrapper<>();

        //查询总记录有多少条
        long count = statisticService.count(lambdaQueryWrapper);

        //组装查询最后一条记录的条件构造器
        lastDayWrapper.eq(Statistic::getId, count);

        //获得最后一条记录是星期几
        int lastDay = DayOfTheWeek.dayOfTheWeek(statisticService.getOne(lastDayWrapper).getCreateAt());

        //获得医院数量
        long countHospital = hospitalService.count();

        //不同的情况两个礼拜的第一天的要求不同 (总记录数是否达到两个礼拜的记录数)
        int firstDay;

        //传递数据的集合
        List<Long> list = new ArrayList<>();

        //组装条件构造器
        if (count <= countHospital * 14) {
            //若总记录数小于等于14天 则第一条记录即为 firstDay
            firstDayWrapper.eq(Statistic::getId, 1);
        } else {
            //若记录数大于14天 则第一条记录为 (count - countHospital * lastDay - 7 * countHospital)
            firstDayWrapper.eq(Statistic::getId, count - countHospital * lastDay - 7 * countHospital);
        }

        //判断firstDay是星期几
        firstDay = DayOfTheWeek.dayOfTheWeek(statisticService.getOne(firstDayWrapper).getCreateAt());

        //只要第一条记录不是星期一 就补0
        if (firstDay != 1) {
            for (int i = 1; i < firstDay; i++) {
                list.add(0L);
            }
        }

        //填充真实数据
        for (int i = 1; i <= count; i += countHospital) {
            LambdaQueryWrapper<Statistic> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Statistic::getId, i);
            switch (type) {
                case "bill" -> list.add(statisticService.getOne(queryWrapper).getBillTotal());
                case "volunteer" -> list.add(statisticService.getOne(queryWrapper).getVolunteerNum());
                case "veteran" -> list.add(statisticService.getOne(queryWrapper).getVeteranNum());
                case "retired" -> list.add(statisticService.getOne(queryWrapper).getRetiredNum());
                case "needy" -> list.add(statisticService.getOne(queryWrapper).getNeedyNum());
                default -> throw new IllegalStateException("Unexpected value: " + type);
            }

        }

        //只要最后一条记录不是星期日 就补0
        if (lastDay != 7) {
            while (list.size() < 14) {
                list.add(0L);
            }
        }

        //返回值
        return list;
    }
}
